﻿using System;
using System.Collections.Generic;
using System.Text;
using XDesigner.AppFramework.DOM ;
using XDesigner.ORM;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Data;

using System.Collections;
using System.Data;
using XDesigner.AppFramework.Actions;

namespace XDesigner.AppFramework
{
    public class AppFrameworkClass : System.ComponentModel.Component
    {
        //private static AppFrameworkClass _Current = null;

        //public static AppFrameworkClass Current
        //{
        //    get 
        //    {
        //        if (_Current == null)
        //        {
        //            _Current = new AppFrameworkClass();
        //        }
        //        return _Current;
        //    }
        //}

        public AppFrameworkClass()
        {
            this.Document._Engine = this;
            this.ORMEngine.AddType(typeof(AppConfigItem));
            this.ORMEngine.AddType(typeof(AppDepartment));
            this.ORMEngine.AddType(typeof(AppPermission));
            this.ORMEngine.AddType(typeof(AppRole));
            this.ORMEngine.AddType(typeof(AppUser));
            this.ORMEngine.AddType(typeof(AppCategory));
            this.ORMEngine.AddType(typeof(AppCategoryValue));
        }

        private AppActionList _Actions = new AppActionList();

        public AppActionList Actions
        {
            get 
            {
                if (_Actions != null)
                {
                    _Actions.Framework = this;
                }
                return _Actions; 
            }
            set
            {
                _Actions = value; 
            }
        }

        private AppDocument _Document = new AppDocument();

        public AppDocument Document
        {
            get
            {
                return _Document; 
            }
            set
            {
                _Document = value;
                if (_Document != null)
                {
                    _Document._Engine = this;
                }
            }
        }

        private ORMEngine _ORMEngine = new ORMEngine();
        [System.ComponentModel.Browsable(false)]
        public ORMEngine ORMEngine
        {
            get
            {
                return _ORMEngine; 
            }
            set
            {
                _ORMEngine = value;
            }
        }

        [System.ComponentModel.Browsable( false )]
        public ORMDataBase DataBase
        {
            get
            {
                if (_ORMEngine == null)
                    return null;
                else
                    return _ORMEngine.DataBase;
            }
            set
            {
                if (_ORMEngine != null)
                {
                    _ORMEngine.DataBase = value;
                }
            }
        }

        private string _Name = "AppFramework";

        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }

        private string _Title = System.AppDomain.CurrentDomain.FriendlyName;

        public string Title
        {
            get { return _Title; }
            set { _Title = value; }
        }

        private AppCategoryList _Categorys = null;
        [System.ComponentModel.Browsable( false )]
        public AppCategoryList Categorys
        {
            get 
            {
                if (_Categorys == null)
                {
                    Array list = this.ORMEngine.ReadAllInstances(typeof(AppCategory));
                    AppCategoryList result = new AppCategoryList();
                    if (list != null)
                    {
                        foreach (AppCategory item in list)
                        {
                            result.Add(item);
                        }
                    }
                    _Categorys = result;
                }
                return _Categorys; 
            }
            set
            {
                _Categorys = value; 
            }
        }

        
        private class DesignTimeSite : System.ComponentModel.ISite
        {
            #region ISite 成员

            internal IComponent _Component = null;

            IComponent ISite.Component
            {
                get { return _Component; }
            }

            internal IContainer _Container = null;
            IContainer ISite.Container
            {
                get { return _Container;}
            }

            internal bool _DesignMode = false;
            bool ISite.DesignMode
            {
                get { return _DesignMode; }
            }

            internal string _Name = null;
            string ISite.Name
            {
                get
                {
                    return _Name;
                }
                set
                {
                    _Name = value;
                }
            }

            #endregion

            #region IServiceProvider 成员

            object IServiceProvider.GetService(Type serviceType)
            {
                return null;
            }

            #endregion
        }//private class DesignTimeSite : System.ComponentModel.ISite


        private static AppFrameworkClass _DesignTimeFramework = null;
        internal static AppFrameworkClass GetDesignTimeFramework(System.ComponentModel.Design.IDesignerHost host)
        {
            if (_DesignTimeFramework == null)
            {
                ITypeDiscoveryService svc = (ITypeDiscoveryService)host.GetService(typeof(ITypeDiscoveryService));
                if (svc != null)
                {
                    ICollection ts = svc.GetTypes(typeof(AppFrameworkClass), false);
                    if (ts != null)
                    {
                        Type descType = null;
                        string connName = null;
                        foreach (Type t in ts)
                        {
                            MainAppFrameworkTypeAttribute attr = (MainAppFrameworkTypeAttribute)Attribute.GetCustomAttribute(t, typeof(MainAppFrameworkTypeAttribute), true);
                            if (attr != null)
                            {
                                descType = t;
                                connName = attr.ConnectionName;
                                break;
                            }
                        }//foreach
                        if (descType == null)
                        {
                            descType = typeof(AppFrameworkClass);
                        }

                        AppFrameworkClass af = (AppFrameworkClass)System.Activator.CreateInstance(descType);
                        DesignTimeSite site = new DesignTimeSite();
                        site._Name = af.Name;
                        site._Component = af;
                        site._Container = host.Container;
                        site._DesignMode = true;
                        af.Site = site;

                        IDataEnvironment data = (IDataEnvironment)host.GetService(typeof(IDataEnvironment));
                        if (data != null)
                        {
                            foreach (DesignerDataConnection conn in data.Connections)
                            {
                                if (HasContent(connName))
                                {
                                    if (string.Compare(conn.Name, connName.Trim(), true) == 0)
                                    {
                                        af.DataBase.Connection = data.GetDesignTimeConnection(conn);
                                        break;
                                    }
                                }
                                else
                                {
                                    af.DataBase.Connection = data.GetDesignTimeConnection( conn);
                                    break;
                                }
                            }//foreach
                        }//if
                        _DesignTimeFramework = af;
                    }//if
                }//if
            }//if
            return _DesignTimeFramework;
        }

        private static bool HasContent(string v)
        {
            return v != null && v.Trim().Length > 0;
        }

        public override string ToString()
        {
            return this.Title;
        }
    }

    [AttributeUsage( AttributeTargets.Assembly | AttributeTargets.Class )]
    public class MainAppFrameworkTypeAttribute : Attribute
    {
        private string _ConnectionName = null;

        public string ConnectionName
        {
            get { return _ConnectionName; }
            set { _ConnectionName = value; }
        }

        //private string _ConnectionString = null;
        //public string ConnectionString
        //{
        //    get { return _ConnectionString; }
        //    set { _ConnectionString = value; }
        //}

        //private string _ConnectionProviderName = null;

        //public string ConnectionProviderName
        //{
        //    get { return _ConnectionProviderName; }
        //    set { _ConnectionProviderName = value; }
        //}
    }
}
